Таймауты при работе с внешними ресурсами
Область применения: управляемое приложение, обычное приложение.
1. При работе с внешними ресурсами с помощью объектов WSОпределения, WSПрокси, HTTPСоединение, FTPСоединение, ИнтернетПочтовыйПрофиль следует задавать таймаут – предельное время ожидания выполнения операции. В противном случае, в результате бесконечного ожидания программа зависнет или часть функционала программы станет недоступна.
Установка таймаута является защитой от целого ряда внешних факторов:
- нестабильного подключения к Интернету, когда регулярно происходит прерывание связи, и система не может получить цельный ответ сервера, к которому выполняется подключение;
- при включенных антивирусных программах или при неправильных настройках брандмауэра;
- неправильной настройки прокси-сервера;
- ненадежной работы веб-сервера из-за возросшей нагрузки или некорректной работы скриптов.
Например, при получении описания веб-сервиса и вызове его операций – если удаленная сторона долго не отвечает (например, выключена, находится на обслуживании или возникли временные неполадки), ожидание ответа может длиться бесконечно. Поэтому если веб-сервис был вызван в результате интерактивных действий пользователя, то внешне будет выглядеть так, что «программа зависла»; а если веб-сервис вызывается из регламентного задания, то связанная с ним часть функционала программы может стать недоступна.
2. В общем виде, время выполнения операции с внешними ресурсами складывается из шести этапов:
- DNS Lookup — время, потраченное на определение IP адреса по доменному имени (если применимо);
- Connect — установка соединения с веб-сервером по полученному IP-адресу;
- Send — отправка данных на веб-сервер;
- Wait — ждем, пока данные дойдут до веб-сервера и он их обработает;
- Receive — получение ответа от веб-сервера;
- Cache Read – получение данных от веб-сервера.
Например, при таймауте в 60 секунд программа и вызываемый внешний ресурс должны успеть выполнить шесть выше перечисленных этапов операции, иначе соединение будет разорвано, а передача данных прервана. Однако если в процессе выполнения операции возникнет сбой, то система и/или пользователь будет зря ожидать 60 секунд.
Поэтому величину таймаута рекомендуется определять, исходя из ожидаемого времени выполнения конкретной операции:
- Для быстрых операций (например, проверка доступности сервера) величина таймаута должна выбираться, соответственно, небольшой;
- В общем случае, не следует выбирать таймаут более 3 минут, чтобы при недоступности удаленной стороны не допустить эффект «зависания» программы;
- Но если операция выполняется долго из-за этапов Send или Cache Read, т.е. это передача больших объемов данных на веб-сервер или загрузка большого файла с внешнего ресурса, то следует устанавливать большой таймаут, исходя из оценки объема передаваемых данных, но не более 12 часов.
Подобнее о рекомендуемых величинах таймаута для различных операций см. в таблице п. 4.
3. Рекомендации по снижению величин таймаута и повышению отзывчивости программы при работе с внешними ресурсами.
3.1. При разработке веб-сервисов, на операции которых предусмотрен таймаут более 20 секунд (ориентировочно), рекомендуется:
- предусмотреть в веб-сервисе отдельную контрольную операцию Ping;
- при работе с этим веб-сервисом, предварительно получать для нее прокси с небольшим таймаутом в 7 секунд и вызывать контрольную операцию Ping;
- только после этого получать основной прокси.
Пример вызова веб-сервиса.
| Неправильно |
Правильно |
|
Реализация модуля веб-сервиса PingPong: | |
|
Функция Pong(Знач Параметр) |
Функция Ping() Функция Pong(Знач Параметр) |
|
Реализация вызывающей стороны (без использования Библиотеки стандартных подсистем): | |
|
// Ждем не более минуты |
// Ждем не более 3 секунд // Сервис жив, далее работаем с ним и ждем не более минуты |
При использовании Библиотеки стандартных подсистем:
- для работы с веб-сервисами предназначена функция WSПрокси общего модуля ОбщегоНазначения (включает в себя поддержку контрольной операции Ping);
- для получения данных по протоколам HTTP(S) и FTP(S) – подсистема «Получение файлов через Интернет».
Пример реализации вызывающей стороны с использованием Библиотеки стандартных подсистем:
// Сделать контрольный вызов Ping и ждать не более минуты на дальнейших операциях.
PingPong = ОбщегоНазначения.WSПрокси(АдресВебСервиса,..., 60, Истина);
// Сервис точно жив, далее работаем с ним.
Результат = PingPong.Pong(НСтр("ru = 'Мяч'"));
3.2. Для других видов внешних ресурсов (не веб-сервисов) рекомендуется применять аналоги операции Ping. Например:
- для сервисов, работающих через REST API – это контрольная отправка тестовой команды; в большинстве случаев, если ответ с кодом 200, то сервис работает;
- для FTP/WebDAV-ресурсов – это контрольная загрузка (отправка) файла-пустышки.
3.3. Веб-сервисы, операции, которых занимают объективно много времени из-за этапа Wait (т.е. долго отрабатывает само веб-приложение), и они не могут быть ускорены (оптимизированы) по объективным причинам, следует переводить на асинхронный режим выполнения:
- запускать фоновое задание для выполнения подобной «тяжелой» операции,
- и предусмотреть дополнительные операции по проверке готовности и получению результата.
Пример асинхронного вызова веб-сервиса.
| Неправильно |
Правильно |
|
Реализация модуля веб-сервиса Long: | |
|
Функция GetData() |
Функция StartDoLong() Функция IsReady(Знач ИдентификаторОперации) Функция GetData(Знач ИдентификаторОперации) |
|
Реализация вызывающей стороны: | |
|
Long = Новый WSПрокси(АдресВебСервиса, , , , , 600); // ждем 10 мин |
Long = Новый WSПрокси(АдресВебСервиса, , , , , 600); // ждем 10 мин |
4. Рекомендуемые величины таймаутов для различных операций:
| Операция | Таймаут (секунд) |
| Получение описания веб-сервиса | 7 |
| Проверка корректности введенного адреса, взаимодействие с менеджером сервиса в модели сервиса и прочие «быстрые» операции | 10-20 |
| Получение сведений об одном контрагенте, обмен сообщениями, отправка SMS, удаленное администрирование ИБ в модели сервиса | 60-1201 |
| Передача сообщений обмена данными через веб-сервис или получение файлов из внешнего ресурса до 1 Мб. | 120-1801 |
| Загрузка файлов более 1 Мб | Если известен размер файла, то размер в мегабайтах * 1282, иначе предельное время загрузки, но не более 43200 3 |
1 Следует вызывать только после контрольной операции Ping.
2 Загрузка 1 мегабайта данных занимает 128 секунд, при скорости 64 кбит/с, т.к. сотовые операторы в определенных случаях ограничивают скорость загрузки этой величиной.
3 Таймаут продолжительностью 43200(12 часов) сек. является компромиссным решением, т.к. в случае нештатной ситуации процесс «отвиснет» на следующее утро и вернет управление, в отличие от полностью зависнувшей программы при неустановленном таймауте.